#define _CRT_SECURE_NO_WARNINGS 1

#include "LinkTable.h"

LinkNode* LinkNodeCreate(LinkData num) {
	LinkNode* plist = (LinkNode*)calloc(1, sizeof(LinkNode));
	if (NULL == plist) {
		perror("LinkNodeCreate->calloc");
		return NULL;
	}
	else {
		plist->data = num;
		plist->next = NULL;
		return plist;
	}
}

void LinkNodePrint(LinkNode* plist) {
	LinkNode* newnode = plist;
	while (newnode != NULL) {
		printf("%d->", newnode->data);
		newnode = newnode->next;
	}
	printf("NULL\n");
}

void LinkNodePushBack(LinkNode** pplist, LinkData num) {
	assert(pplist);
	LinkNode* newnode = LinkNodeCreate(num);
	if (*pplist == NULL) {
		*pplist = newnode;
		return;
	}
	else {
		LinkNode* tail = *pplist;
		while (tail->next != NULL) {
			tail = tail->next;
		}
		tail->next = newnode;
	}
}

void LinkNodePushFront(LinkNode** pplist, LinkData num) {
	assert(pplist);
	LinkNode* newnode = LinkNodeCreate(num);
	newnode->next = *pplist;
	*pplist = newnode;
}

void LinkNodePopBack(LinkNode** pplist) {
	assert(pplist);
	assert(*pplist);
	if ((*pplist)->next == NULL) {
		free(*pplist);
		*pplist = NULL;
	}
	else {
		LinkNode* prev = NULL;
		LinkNode* tail = *pplist;
		while (tail->next != NULL) {
			prev = tail;
			tail = tail->next;
		}
		prev->next = NULL;
		free(tail);
		tail = NULL;
	}
}

void LinkNodePopFront(LinkNode** pplist) {
	assert(pplist);
	assert(*pplist);
	LinkNode* cul = *pplist;
	*pplist = cul->next;
	free(cul);
	cul = NULL;
}

LinkNode* LinkNodeSearch(LinkNode* plist, LinkData vul) {
	assert(plist);
	LinkNode* newnode = plist;
	while (newnode) {
		if (newnode->data == vul)
			return newnode;
		else
			newnode = newnode->next;
	}
	return NULL;
}

void LinkNodeInsert(LinkNode** pplist, LinkData vul, LinkData num) {
	assert(pplist);
	LinkNode* pos = LinkNodeSearch(*pplist,vul);
	assert(pos);
	LinkNode* newnode = LinkNodeCreate(num);
	LinkNode* insert = *pplist;
	if (*pplist == pos) {
		*pplist = newnode;
		newnode->next = pos;
	}
	else {
		while (insert->next != pos) {
			insert = insert->next;
		}
		insert->next = newnode;
		newnode->next = pos;
	}
}

void LinkNodeErase(LinkNode** pplist, LinkData vul) {
	assert(pplist);
	LinkNode* pos = LinkNodeSearch(*pplist, vul);
	assert(pos);
	LinkNode* erase = *pplist;
	if (*pplist == pos) {
		*pplist = pos->next;
		free(pos);
		pos = NULL;
	}
	else {
		while (erase->next != pos) {
			erase = erase->next;
		}
		erase->next = pos->next;
		free(pos);
		pos = NULL;
	}
}

void LinkNodeInsertAfter(LinkNode** pplist, LinkData vul, LinkData num) {
	assert(pplist);
	LinkNode* pos = LinkNodeSearch(*pplist, vul);
	assert(pos);
	LinkNode* newnode = LinkNodeCreate(num);
	newnode->next = pos->next;
	pos->next = newnode;
}

void LinkNodeEraseAfter(LinkNode** pplist, LinkData vul) {
	assert(pplist);
	LinkNode* pos = LinkNodeSearch(*pplist, vul);
	assert(pos);
	assert(pos->next);
	LinkNode* erase = pos->next;
	pos->next = erase->next;
	free(erase);
	erase = NULL;
}

void LinkDestroy(LinkNode** pplist) {
	assert(pplist);
	LinkNode* cur = *pplist;
	while (cur) {
		LinkNode* pos = cur->next;
		free(cur);
		cur = pos;
	}
	*pplist = NULL;
}